/*
 * @lc app=leetcode.cn id=652 lang=swift
 *
 * [652] 寻找重复的子树
 */

// @lc code=start
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     public var val: Int
 *     public var left: TreeNode?
 *     public var right: TreeNode?
 *     public init() { self.val = 0; self.left = nil; self.right = nil; }
 *     public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
 *     public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
 *         self.val = val
 *         self.left = left
 *         self.right = right
 *     }
 * }
 */
class Solution {
    func findDuplicateSubtrees(_ root: TreeNode?) -> [TreeNode?] {
        var memo: [String: Int] = [:]
        var res: [TreeNode] = []
        func traverse(_ root: TreeNode?) -> String {
            if root == nil { return "#" }

            let left = traverse(root?.left)
            let right = traverse(root?.right)

            let subTree = "\(left),\(right),\(root!.val)"

            let freq = memo[subTree, default: 0]
            if freq == 1 {
                res.append(root!)
            }

            memo[subTree] = freq+1

            return subTree
        }
        traverse(root)
        return res
    }
}
// @lc code=end

